package cn.com.jdyun.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Transaction;

public class Test {

    // 当前主机cpu个数：用于初始化线程池
    private static final int nThreads = Runtime.getRuntime().availableProcessors();
    // 初始线程池,最大线程数,程池的工作线程空闲后保持存活的时间:0,时间单位：毫秒,用来储存等待执行任务的队列,线程工厂，当队列和线程池都满了时拒绝任务的策略
    private static final ExecutorService pool = new ThreadPoolExecutor(nThreads, nThreads * 2, 0L,
            TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(256),
            new ThreadFactoryBuilder().setNameFormat("thread-%d").build(), new ThreadPoolExecutor.AbortPolicy());
    private static final Set<String> keys = new HashSet<String>();

    public static JedisPoolConfig getRedisConfig() {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(30);
        config.setMaxIdle(10);
        config.setMinIdle(1);
        config.setMaxWaitMillis(15000);
        config.setTestOnReturn(true);
        return config;
    }

    public static JedisPool getJedisPool() {
        JedisPoolConfig config = getRedisConfig();
        JedisPool pool = new JedisPool(config, "192.168.0.143", 6379, 5000, "123456");
        return pool;
    }

    public static Jedis getResource() {
        return getJedisPool().getResource();
    }

    public static void returnResource(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    public static void main1(String[] args) throws InterruptedException {
        final String watchkey = "watchkey";
        final String logs = "logs";
        int i = 0;
        while (i < 1000) {
            System.out.println(">>> i:" + i);
            final int ii = i;
            keys.add(i + "");
            while (keys.size() >= 200) {
                Thread.sleep(1000);
            }
            pool.execute(() -> {
                try {
                    Jedis jedis = getResource();
                    String poolAmount = null;
                    BigDecimal lastValue = null;
                    int j = 0;
                    while (true) {
                        jedis.watch(watchkey);// watchkey
                        poolAmount = jedis.get(watchkey);
                        if (poolAmount == null) {
                            poolAmount = "0";
                        }
                        lastValue = new BigDecimal(poolAmount).add(new BigDecimal("1"));
                        Transaction tx = jedis.multi();// 开启事务
                        tx.set(watchkey, lastValue.toString());
                        List<Object> list = tx.exec();// 提交事务，如果此时watchkey被改动了，则返回null
                        if (list != null && !list.isEmpty()) {
                            jedis.hset(logs, String.format("%04d", ii) + "." + String.format("%04d", j), poolAmount + "," + lastValue.toString() + ":ok");
                            break;
                        }
                        jedis.hset(logs, String.format("%04d", ii) + "." + String.format("%04d", j), poolAmount + "," + lastValue.toString() + ":ok");
                        try {
                            Thread.sleep(100); //如果失败，暂停100ms;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(">>> i.j:" + ii + "." + j);
                        j++;
                    }

                    jedis.close();

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    keys.remove(ii + "");
                }
            });
            i++;
            if (i % 9 == 0) {
                Thread.sleep(1000);
            }
        }
        System.out.println("finished");
    }

    public static void main(String[] args) {
//        BigDecimal num3 = num1.divide(num2，6);
    }
    
    public static void format1(String pattern,double value){   // 此方法专门用于完成数字的格式化显示  
        DecimalFormat df = null ;           // 声明一个DecimalFormat类的对象  
        df = new DecimalFormat(pattern) ;   // 实例化对象，传入模板  
        String str = df.format(Double.valueOf("0")) ;     // 格式化数字  
        System.out.println("使用" + pattern  
            + "格式化数字" + value + "：" + str) ;  
    }
}
